package com.ruoyi.common.utils.file;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.imageio.ImageIO;
import javax.swing.*;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.*;
import java.nio.file.Files;
import java.nio.file.Paths;

/**
 * 功能：图片水印工具类
 */
public class ImageRemarkUtil {
    private static final Logger log = LoggerFactory.getLogger(ImageRemarkUtil.class);

    // 水印横向位置
    private static int positionWidth = 1000;
    // 水印纵向位置
    private static int positionHeight = 1000;
    // 水印文字字体
    private static Font font = new Font("微软雅黑", Font.PLAIN, 55);
    // 水印文字颜色
    private static Color color = Color.WHITE;

    public static void main(String[] args) throws IOException {
        String waterMarkContent = "检测时间：#检测时间#   检测点名称：#检测点名称#   桩号：#桩号#   车牌号：#车牌号# ###" +
                "车牌颜色：#车牌颜色#   轴数：#轴数#   车道：#车道#   总质量：#总质量#   超限量：#超限量#   超限率：#超限率#   车速：#车速#   车型：#车型#   是否逆行：#是否逆行# ###" +
                "是否跨道：#是否跨道#   取证设备编号：#取证设备编号#   唯一标识：#唯一标识#   防伪标识：#防伪标识#  ###";
        String iconImgPath = "D:\\test\\X.jpg";
        String srcImgPath = "D:\\test\\1.jpg";
        String targetPath = "D:\\test\\666.jpg";
        double widthRate = 0.01;
        File file = new File(srcImgPath);
        Image srcImg = ImageIO.read(file);
        ImageRemarkUtil.markImageByText(srcImg, waterMarkContent, targetPath, widthRate);

//        String iconPath = "D:\\test\\2.jpg";
        File iconFile = new File(iconImgPath);
        Image iconImage = ImageIO.read(iconFile);
//        ImageIcon imgIcon = new ImageIcon("D:\\test\\2.jpg");
        ImageRemarkUtil.markImageByIcon(iconImgPath, targetPath, targetPath);
    }

    /**
     * 给图片添加水印文字、可设置水印文字的旋转角度
     *
     * @param srcImg     图片流
     * @param logoText   水印文字
     * @param targetPath 存放地址
     * @param widthRate  宽带比例
     */
    public static void markImageByText(Image srcImg, String logoText, String targetPath, double widthRate) {
        InputStream is = null;
        OutputStream os = null;
        try {
            // 1、源图片
            int imgWidth = srcImg.getWidth(null);
            int imgHeight = srcImg.getHeight(null);
            BufferedImage buffImg = new BufferedImage(imgWidth, imgHeight, BufferedImage.TYPE_INT_RGB);
            // 2、得到画笔对象
            Graphics2D g = buffImg.createGraphics();
            // 3、设置对线段的锯齿状边缘处理
            g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
            g.drawImage(srcImg.getScaledInstance(imgWidth, imgHeight, Image.SCALE_SMOOTH), 0, 0, null);
            // 4、设置水印旋转
            // 5、设置水印文字颜色
            g.setColor(color);
            // 6、设置水印文字Font
            int size = font.getSize();
            g.setFont(font);
            // 7、设置水印文字透明度
            g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, 0.0F));
            // 8、第一参数->设置的内容，后面两个参数->文字在图片上的坐标位置(x,y)
            if (logoText.contains("###")) {
                String[] waterMarkContentList = logoText.split("###");
                // 将换行后的文字放入新的集合
                int startRow = imgHeight - waterMarkContentList.length * size;
                g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, 0.0F));
                g.setColor(color);
                g.fillRect(0, startRow - size * 2, imgWidth, startRow + size);
                // 释放对象 透明度设置结束
                g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER));
                g.setColor(Color.WHITE);
                for (int i = 0; i < waterMarkContentList.length; i++) {
                    int x = (int) Math.floor(imgWidth * widthRate);
                    int y = startRow + i * size;
                    g.drawString(waterMarkContentList[i], x, y);//画出水印,并设置水印位置
                }
            } else {
                int x = (int) Math.floor(imgWidth * widthRate);
                int y = (int) Math.floor(imgHeight);
                g.drawString(logoText, x, y);
            }
            // 9、释放资源
            g.dispose();
            // 10、生成图片
            String fileType = "jpg";
            ByteArrayOutputStream stream = new ByteArrayOutputStream();
            ImageIO.write(buffImg, fileType.toUpperCase(), stream);
            os = Files.newOutputStream(Paths.get(targetPath));
            ImageIO.write(buffImg, fileType.toUpperCase(), os);
        } catch (Exception e) {
            log.error("加水印异常：{}", e.getMessage());
        } finally {
            try {
                if (null != os)
                    os.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 给图片添加水印图片
     *
     * @param iconPath   水印图片路径
     * @param srcImgPath 源图片路径
     * @param targetPath 目标图片路径
     */
    public static void markImageByIcon(String iconPath, String srcImgPath, String targetPath) {
        markImageByIcon(iconPath, srcImgPath, targetPath, null);
    }

    /**
     * 给图片添加水印图片、可设置水印图片旋转角度
     *
     * @param iconPath   水印图片路径
     * @param srcImgPath 源图片路径
     * @param targetPath 目标图片路径
     * @param degree     水印图片旋转角度
     */
    public static void markImageByIcon(String iconPath, String srcImgPath, String targetPath, Integer degree) {
        OutputStream os = null;
        try {
            Image srcImg = ImageIO.read(new File(srcImgPath));
            int imgWidth = srcImg.getWidth(null);
            int imgHeight = srcImg.getHeight(null);
            BufferedImage buffImg = new BufferedImage(imgWidth, imgHeight, BufferedImage.TYPE_INT_RGB);
            // 1、得到画笔对象
            Graphics2D g = buffImg.createGraphics();
            // 2、设置对线段的锯齿状边缘处理
            g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
            g.drawImage(srcImg.getScaledInstance(imgWidth, imgHeight, Image.SCALE_SMOOTH), 0, 0, null);
            // 3、设置水印旋转
            if (null != degree) {
                g.rotate(Math.toRadians(degree), (double) buffImg.getWidth() / 2, (double) buffImg.getHeight() / 2);
            }
            // 4、水印图片的路径 水印图片一般为gif或者png的，这样可设置透明度
            ImageIcon imgIcon = new ImageIcon(iconPath);
            // 5、得到Image对象。
            Image img = imgIcon.getImage();
            g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, 1.0F));
            // 6、水印图片的位置 右上角
            int iconX = imgWidth - positionWidth;
            int iconY = 0;
            g.drawImage(img, iconX, iconY, positionWidth, positionHeight, null);
            g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER));
            // 7、释放资源
            g.dispose();
            // 8、生成图片
            os = Files.newOutputStream(Paths.get(targetPath));
            ImageIO.write(buffImg, "jpg", os);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (null != os)
                    os.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 给图片添加水印文字
     *
     * @param logoText   水印文字
     * @param srcImgPath 源图片路径
     * @param targetPath 目标图片路径
     */
    public static void markImageByText(String logoText, String srcImgPath, String targetPath, double widthRate) {
        markImageByText(logoText, srcImgPath, targetPath, null, widthRate);
    }

    /**
     * 给图片添加水印文字、可设置水印文字的旋转角度
     *
     * @param logoText   水印文字
     * @param srcImgPath 图片地址
     * @param targetPath 存放地址
     * @param degree     旋转角度
     */
    public static void markImageByText(String logoText, String srcImgPath, String targetPath, Integer degree, double widthRate) {
        InputStream is = null;
        OutputStream os = null;
        try {
            // 1、源图片
            File file = new File(srcImgPath);
            Image srcImg = ImageIO.read(file);
            BufferedImage buffImg = new BufferedImage(srcImg.getWidth(null), srcImg.getHeight(null), BufferedImage.TYPE_INT_RGB);
            // 2、得到画笔对象
            Graphics2D g = buffImg.createGraphics();
            // 3、设置对线段的锯齿状边缘处理
            g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
            g.drawImage(srcImg.getScaledInstance(srcImg.getWidth(null), srcImg.getHeight(null), Image.SCALE_SMOOTH), 0, 0, null);
            // 4、设置水印旋转
            if (null != degree) {
                g.rotate(Math.toRadians(degree), (double) buffImg.getWidth() / 2, (double) buffImg.getHeight() / 2);
            }
            // 5、设置水印文字颜色
            g.setColor(color);
            // 6、设置水印文字Font
//            int size = srcImg.getWidth(null) / 300 * 10;
//            if (size == 0) {
//                size = 10;
//            }
//            Font font = new Font("宋体", Font.BOLD, size);
            int size = font.getSize();
            g.setFont(font);
            // 7、设置水印文字透明度
            g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, 0.0F));
            // 8、第一参数->设置的内容，后面两个参数->文字在图片上的坐标位置(x,y)
            if (logoText.contains("###")) {
                String[] waterMarkContentList = logoText.split("###");
                // 将换行后的文字放入新的集合
                int startRow = srcImg.getHeight(null) - waterMarkContentList.length * size;
                g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, 0.0F));
                g.setColor(color);
//                g.setStroke(new BasicStroke(1f));
                g.fillRect(0, startRow - size * 2, srcImg.getWidth(null), startRow + size);
                // 释放对象 透明度设置结束
                g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER));
                g.setColor(Color.WHITE);
                for (int i = 0; i < waterMarkContentList.length; i++) {
//                	JLabel label = new JLabel(waterMarkContentList[i]);/*获取自定义水印信息*/
//                    FontMetrics metrics = label.getFontMetrics(font);
//                    int waterWidth = metrics.stringWidth(label.getText());//文字水印的宽
//                    int rowsNumber = waterWidth/;// 图片的高  除以  文字水印的宽  打印的行数(以文字水印的宽为间隔)
//                    int columnsNumber = width / waterWidth;//图片的宽 除以 文字水印的宽  每行打印的列数(以文字水印的宽为间隔)
                    //g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, 1.0f));
//                    g.drawString(waterMarkContentList[i], (int) Math.floor(srcImg.getWidth(null) * widthRate), startRow + i * size);//画出水印,并设置水印位置
                    int x = (int) Math.floor(srcImg.getWidth(null) * widthRate);
                    int y = startRow + i * size;
                    g.drawString(waterMarkContentList[i], x, y);//画出水印,并设置水印位置
                }
            } else {
                int x = (int) Math.floor(buffImg.getWidth() * widthRate);
                int y = (int) Math.floor(buffImg.getHeight());
                g.drawString(logoText, x, y);
            }
            // 9、释放资源
            g.dispose();
            // 10、生成图片
            String fileType = srcImgPath.substring(srcImgPath.lastIndexOf(".") + 1);
            ByteArrayOutputStream stream = new ByteArrayOutputStream();
            ImageIO.write(buffImg, fileType.toUpperCase(), stream);
            os = Files.newOutputStream(Paths.get(targetPath));
            ImageIO.write(buffImg, fileType.toUpperCase(), os);
            log.info("加水成功");
        } catch (Exception e) {
            log.error("加水印异常：{}", e);
        } finally {
            try {
                if (null != os)
                    os.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

}

